#ifndef LOG_H
#define LOG_H

#include "main.h"
#include "SEGGER_RTT.h"

#define CONSOLE_ENABLE	1

#define RTT_LOG			0
#define UART_LOG		1

#define LOG_SELECT			RTT_LOG

#define LOG_LEVEL_NONE  0 /*!< 不输出日志 */
#define LOG_LEVEL_TEST  1 /*!< 输出测试日志 */
#define LOG_LEVEL_ERROR 2 /*!< 输出错误日志 */
#define LOG_LEVEL_WARN  3 /*!< 输出警告以上日志 */
#define LOG_LEVEL_INFO  4 /*!< 输出信息以上日志 */
#define LOG_LEVEL_DEBUG 5 /*!< 输出调试以上日志 */

//#define LOG_ENABLE_LEVEL LOG_LEVEL_NONE
#define LOG_ENABLE_LEVEL LOG_LEVEL_DEBUG


#ifndef LOG_ENABLE_LEVEL
#define LOG_ENABLE_LEVEL LOG_LEVEL_NONE
#endif // LOG_ENABLE_LEVEL


#if (LOG_SELECT == RTT_LOG)
#if (LOG_ENABLE_LEVEL > LOG_LEVEL_NONE)
void log_write(const char* format, ...) __attribute__((format(printf, 1, 2)));

#define LOGC(color, tag, format, ...) log_write(color "(%lu) " tag " : " format, HAL_GetTick(), ##__VA_ARGS__)
#endif // LOG_LEVEL_NONE

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_TEST)
#define LOGT(tag, format, ...) log_write(RTT_CTRL_TEXT_BRIGHT_CYAN   "(%lu) " tag " : " format"\r\n", HAL_GetTick(), ##__VA_ARGS__)
#else  // LOG_LEVEL_TEST
#define LOGT(tag, format, ...)
#endif // LOG_LEVEL_TEST

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_ERROR)
#define LOGE(tag, format, ...) log_write(RTT_CTRL_TEXT_BRIGHT_RED    "(%lu) " tag " : " format"\r\n", HAL_GetTick(), ##__VA_ARGS__)
#else  // LOG_LEVEL_ERROR
#define LOGE(tag, format, ...)
#endif // LOG_LEVEL_ERROR

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_WARN)
#define LOGW(tag, format, ...) log_write(RTT_CTRL_TEXT_BRIGHT_YELLOW "(%lu) " tag " : " format"\r\n", HAL_GetTick(), ##__VA_ARGS__)
#else  // LOG_LEVEL_WARN
#define LOGW(tag, format, ...)
#endif // LOG_LEVEL_WARN

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_INFO)
#define LOGI(tag, format, ...) log_write(RTT_CTRL_TEXT_BRIGHT_GREEN  "(%lu) " tag " : " format"\r\n", HAL_GetTick(), ##__VA_ARGS__)
#else  // LOG_LEVEL_INFO
#define LOGI(tag, format, ...)
#endif // LOG_LEVEL_INFO

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_DEBUG)
#define LOGD(tag, format, ...) log_write(RTT_CTRL_TEXT_BRIGHT_WHITE  "(%lu) " tag " : " format"\r\n", HAL_GetTick(), ##__VA_ARGS__)
#else  // LOG_LEVEL_DEBUG
#define LOGD(tag, format, ...)
#endif // LOG_LEVEL_DEBUG

#elif (LOG_SELECT == UART_LOG)

#if (LOG_ENABLE_LEVEL > LOG_LEVEL_NONE)
#define LOGC	 Log
#endif // LOG_LEVEL_NONE

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_TEST)
#define LOGT	Log
#else  // LOG_LEVEL_TEST
#define LOGT(tag, format, ...)
#endif // LOG_LEVEL_TEST

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_ERROR)
#define LOGE	Log
#else  // LOG_LEVEL_ERROR
#define LOGE(tag, format, ...)
#endif // LOG_LEVEL_ERROR

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_WARN)
#define LOGW	Log
#else  // LOG_LEVEL_WARN
#define LOGW(tag, format, ...)
#endif // LOG_LEVEL_WARN

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_INFO)
#define LOGI	Log
#else  // LOG_LEVEL_INFO
#define LOGI(tag, format, ...)
#endif

#if (LOG_ENABLE_LEVEL >= LOG_LEVEL_DEBUG)
#define LOGD	Log
#else  // LOG_LEVEL_DEBUG
#define LOGD(tag, format, ...)
#endif // LOG_LEVEL_DEBUG

#endif

void log_init(void);
void log_buf(const char *buf, int len);

#endif // LOG_H
